package com.alibaba.fastjson;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.noear.snack.ONode;
import org.noear.snack.core.utils.DateUtil;

import com.alibaba.fastjson.exception.ParseException;

public abstract class JSON extends AbsJson{

    public static String toJSONString(Object jsonString) {
        try {
        	return ONode.stringify(jsonString);
        } catch (Exception e) {
            throw new ParseException(e);
        }
    }

    public static Object parse(String jsonString) {
        if (isJsonObj(jsonString)) {
            return parseObject(jsonString);
        }
        if (isJsonArray(jsonString)) {
            return parseArray(jsonString);
        }
        try {
        	return ONode.loadStr(jsonString);
        } catch (Exception e) {
            throw new ParseException(e);
        }
    }
    

    public static JSONObject parseObject(String jsonString) {
        try {
//        	final Map map =ONode.deserialize(jsonString, Map.class);
//            return mapToJsonObject(map);
        	 ONode obj = ONode.loadStr(jsonString);
        	 return obj.toObject(JSONObject.class);
        } catch (Exception e) {
            throw new ParseException(e);
        }

    }

    public static <T> T parseObject(String jsonString, Class<T> clazz) {
        try {
            return ONode.deserialize(jsonString, clazz);
        } catch (Exception e) {
            throw new ParseException(e);
        }
    }

    public static JSONArray parseArray(String jsonString) {
        try {
//        	final List list = ONode.deserialize(jsonString, JSONArray.class);
//            return listConvertToJsonArray(list);
        	JSONArray jsonArray =  ONode.deserialize(jsonString, JSONArray.class);
//        	jsonArray.setJson(jsonString);
        	return jsonArray;
        } catch (Exception e) {
            throw new ParseException(e);
        }
    }


    public static <T> List<T> parseArray(String jsonString, Class<T> clazz) {
        try {
//        	List<String> jsonArray = ONode.deserialize(jsonString, (new TypeRef<List<String>>(){}).getClass());
//        	List<T> list = new ArrayList<T>(jsonArray.size());
//        	for(String s:jsonArray) {
//        		T classItem  = ONode.deserialize(s, clazz);
//                list.add(classItem);
//        	}
//        	return list;
        	ONode array = ONode.loadStr(jsonString);
        	return array.toObjectList(clazz);
        } catch (Exception e) {
            throw new ParseException(e);
        }
    }


//    @Deprecated
//    private static JSONArray listConvertToJsonArray(List list) {
//        List<Object> jsonObjects = new ArrayList<>(list.size());
//        for (Object obj : list) {
////            jsonObjects.add(mapToJsonObject((Map<String, Object>) obj));
//        	jsonObjects.add(obj);
//        }
//        return new JSONArray(jsonObjects);
//    }

//    /**
//     * jackson parse出来的是map和list,所以把map和list转换为jsonObject和jsonArray
//     *
//     * @param map
//     * @return
//     */
//    @Deprecated
//    private static JSONObject mapToJsonObject(Map<String, Object> map) {
//        JSONObject jsonObject = new JSONObject(map.size());
//        for (Map.Entry<String, Object> entry : map.entrySet()) {
//            final Object value = entry.getValue();
//            if (value instanceof Map) {
//                jsonObject.put(entry.getKey(), mapToJsonObject((Map<String, Object>) value));
//            } else if (value instanceof List) {
//                final List listVal = (List) value;
//                JSONArray objects = new JSONArray(listVal.size());
//                for (Object o : listVal) {
//                    if (o instanceof Map) {
//                        objects.add(mapToJsonObject((Map<String, Object>) o));
//                    } else if (o instanceof List) {
//                        objects.add(listConvertToJsonArray((List) o));
//                    }
//                }
//                jsonObject.put(entry.getKey(), objects);
//            } else {
//                jsonObject.put(entry.getKey(), value);
//            }
//        }
//        return jsonObject;
//    }

    public static String toJSON(Object jsonString) {
    	try {
        	return ONode.stringify(jsonString);
        } catch (Exception e) {
            throw new ParseException(e);
        }
    }
    
    Date castToDate(Object value, String format) {
        if (value == null) {
            return null;
        }

        if (value instanceof Date) { // 使用频率最高的，应优先处理
            return (Date) value;
        }

        if (value instanceof Calendar) {
            return ((Calendar) value).getTime();
        }

        long longValue = -1;

        if (value instanceof BigDecimal) {
            longValue =  TypeUtils.longValue((BigDecimal) value);
            return new Date(longValue);
        }

        if (value instanceof Number) {
            longValue = ((Number) value).longValue();
            if ("unixtime".equals(format)) {
                longValue *= 1000;
            }
            return new Date(longValue);
        }

        if (value instanceof String) {
        	String strVal = (String) value;
        	if (strVal.startsWith("/Date(") && strVal.endsWith(")/")) {
                strVal = strVal.substring(6, strVal.length() - 2);
            }
            try {
            	longValue = Long.parseLong(strVal);
            	if(longValue > 0) {
            		return new Date(longValue);
            	}
				return DateUtil.parse(strVal);
			} catch (java.text.ParseException e) {
				throw new ParseException("can not cast to date, value : " + value);
			}
        }

        return new Date(longValue);
    }
    
}
